﻿using System;
using System.Collections.Generic;
using System.Linq;
using Shell.Common;
using Shell.KnowledgeBase;

namespace Shell.Nodes
{
    public class SyntaxReductionNode : BranchNode
    {
        private readonly Statement _statementToReduce;
        private readonly IEnumerable<SyntaxRule> _rules;
        private readonly Func<Statement, Node> _next;

        public SyntaxReductionNode(
            Statement statementToReduce,
            IEnumerable<SyntaxRule> rules,
            Func<Statement, Node> next)
        {
            _statementToReduce = statementToReduce;
            _rules = rules;
            _next = next;
        }

        public override IEnumerable<WeightedNode> Process()
        {
            var reduceResult = _rules.SelectMany(rule => _statementToReduce.Reduce(rule)).ToArray();

            return Identity(
                reduceResult.Any()
                    ? reduceResult.Select(_ => new SyntaxReductionNode(_, _rules, _next))
                    : _next(_statementToReduce).Yield());
        }

        public override string ToString()
        {
            return string.Format("Reduce: {0}", _statementToReduce);
        }
    }
}